<!--滑动容器组件-->
<!--  
  传入参数：
    topId : 需要滑动到顶部的内部子元素的id  --string

  交互方法：
    scroll : 返回滑动函数 （boxHeight 滑动区域的真实高度；boxScrollTop 目前滑动的距离；boxScrollHeight 滚动条总高度；isDirection 当前滚动的方向(upward:向上;downward:向下)）
    scrollBottom : 滑动到底部触发函数
  
  使用介绍：
    1、运用插槽的形式，故只需要组件引用后，将需要的内容进行写入标签即可
    2、如果需要使用元素置顶功能，则请使用 topId 属性，且插槽内的对应元素要有id值，否则会无效
    3、此组件目前只能提供纵向滑动属性与功能
    4、若是需要对本容器进行其他的改变可以直接在上面套用绑定class名进行改变即可
  
  用法示例：
    <slidingBlock
      class="index-scroll"
      :topId="useId"
      @scroll="boxScroll"
      @scrollBottom="boxScrollBottom"
    >
      <div v-for="item in 5" :key="item" :id="`box${item}`">{{ item }}</div>
    </slidingBlock>
-->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->

<template>
  <div class="slidingBlock" @scroll.stop="boxScroll" ref="slidingBlockBox">
    <slot></slot>
  </div>
</template>

<script>
// 组件引用
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// 接口+方法引用
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

export default {
  // 页面or组件 命名
  name: 'slidingBlock',

  // props传值
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  props: {
    // 置顶的盒子id
    topId: {
      type: [String],
      default: '',
    },
  },

  // 参数变量声明区域
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  data() {
    return {
      /**
       * @常规变量声明区
       */
      // ---------------------------------------------------------------------------------------------
      isDirection: 0, // 方向判断中间值
    }
  },
  // 监听使用区
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  watch: {
    // 监听传入的置顶id值
    topId(msg) {
      let topBox = document.getElementById(msg) // 获取置顶的dom元素
      // 判断如果此id存在，并且能获取到这个dom元素则执行移动到元素上方的操作
      if (msg && topBox) {
        this.$refs.slidingBlockBox.scrollTop = topBox.offsetTop
      }
    },
  },

  // 无内存函数使用区域
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  methods: {
    /**
     * @事件方法区域
     *  */
    // ---------------------------------------------------------------------------------------------
    // 容器滚动函数
    boxScroll(e) {
      let boxHeight = e.target.offsetHeight // 滑动区域的真实高度
      let boxScrollTop = e.target.scrollTop // 目前滑动的距离
      let boxScrollHeight = e.target.scrollHeight // 滚动条总高度

      // 使用父级滚动回调函数，返回 boxHeight 滑动区域的真实高度；boxScrollTop 目前滑动的距离；boxScrollHeight 滚动条总高度；isDirection 当前滚动的方向(upward:向上;downward:向下)
      this.$emit('scroll', {
        boxHeight,
        boxScrollTop,
        boxScrollHeight,
        isDirection: this.isDirection > boxScrollTop ? 'upward' : 'downward',
      })

      // 给方向判断中间值同步目前的滑动距离
      this.isDirection = boxScrollTop

      if (boxScrollHeight <= boxHeight + boxScrollTop) {
        // 滑动到底部触发函数
        this.$emit('scrollBottom')
      }
    },
  },
}
</script>

<style scoped lang="less">
/* 滑动容器组件 */
.slidingBlock {
  width: 100%;
  height: 400px;
  overflow-x: hidden;
  overflow-y: scroll;
  scroll-behavior: smooth;
  position: relative;
}
</style>
